package com.andova.camera.glsurface

import android.content.Context
import android.graphics.SurfaceTexture
import android.hardware.Camera
import android.opengl.GLSurfaceView
import com.andova.cameraview.CameraView
import com.andova.ext.e
import com.andova.ext.i
import com.andova.face.FaceUtil
import com.andova.face.ICameraCheckListener
import com.andova.face.IFaceDetector
import com.andova.face.detector.CameraProvider
import com.andova.face.detector.IPreview

class ACameraPreviewer(private val context: Context, private val preview: IPreview, private val viewport: GLSurfaceView) {
    private var camera: Camera? = null
    private var checkListener: ICameraCheckListener? = null

    @CameraView.Facing
    private var cameraId: Int = 0
    private var orientation = -1
    private var cameraWidth: Int = 0
    private var cameraHeight: Int = 0
    private var minCameraPixel: Long = 0
    private var displayOrientation: Int = 0
    private val cameraProvider = CameraProvider() // todo provide
    private var faceDetector: IFaceDetector? = null

    fun setFaceDetector(faceDetector: IFaceDetector?): IPreview = preview.apply { this@ACameraPreviewer.faceDetector = faceDetector }
    fun setCheckListener(checkListener: ICameraCheckListener?): IPreview = preview.apply { this@ACameraPreviewer.checkListener = checkListener }
    fun setMinCameraPixels(minCameraPixels: Long): IPreview = preview.apply { this@ACameraPreviewer.minCameraPixel = minCameraPixels }
    fun setDisplayOrientation(degree: Int): IPreview = preview.apply { this@ACameraPreviewer.orientation = degree }
    fun setCameraId(cameraId: Int): IPreview = preview.apply { this@ACameraPreviewer.cameraId = cameraId }
    fun getCameraId(): Int = cameraId
    fun closeCamera() {
        faceDetector?.setOpenCamera(false)
        try {
            camera?.setPreviewCallback(null)
            camera?.stopPreview()
            camera?.release()
            camera = null
        } catch (ignore: Exception) {
        }
    }

    fun release() {
        closeCamera()
        faceDetector?.release()
    }

    fun openCamera(surfaceTexture: SurfaceTexture?) {
        camera?.run { return }
        if (!FaceUtil.checkCameraPermission(context)) {
            i("摄像头权限未打开，请打开后再试")
            checkListener?.checkPermission(false)
            return
        }
        // 只有一个摄相头，打开后置
        if (Camera.getNumberOfCameras() == 1) cameraId = CameraView.FACING_BACK
        faceDetector?.setCameraId(cameraId)
        try {
            camera = Camera.open(cameraId)
            // setParameters 针对部分手机通过Camera.open()拿到的Camera对象不为null
            val mParameters = camera?.parameters
            camera?.parameters = mParameters
            if (CameraView.FACING_FRONT == cameraId) i("前置摄像头已开启") else i("后置摄像头已开启")
        } catch (e: Exception) {
            e.printStackTrace()
            //回调权限判定结果
            checkListener?.checkPermission(false)
            //关闭相机
            closeCamera()
            return
        }
        camera ?: return
        //回调权限判定结果
        checkListener?.checkPermission(true)
        var pixels = 0L
        try {
            //获取最大宽高，得出最大支持像素
            val parameters = camera?.parameters
            // getSupportedPictureSizes：获取横屏模式下摄像头支持的PictureSize列表
            FaceUtil.findMaxCameraSize(parameters?.supportedPictureSizes)?.run { pixels = (this.width * this.height).toLong() }
            i("camera max support pixels: $pixels")
            //回调该手机像素值
            if (checkListener != null && minCameraPixel > 0) {
                if (pixels >= minCameraPixel) {
                    checkListener?.checkPixels(pixels, true)
                } else {
                    closeCamera()
                    checkListener?.checkPixels(pixels, false)
                    return
                }
            }
            i("camera size width:$cameraWidth,height:$cameraHeight")
            faceDetector?.setCameraWidth(cameraWidth)
            faceDetector?.setCameraHeight(cameraHeight)
            //设置相机参数
            displayOrientation = FaceUtil.setCameraParams(viewport, faceDetector, checkListener, null, camera, cameraId, cameraWidth, cameraHeight)
            i("camera getPreviewSize width:${camera?.parameters?.previewSize?.width},height:${camera?.parameters?.previewSize?.height}")
            i("camera getPictureSize width:${camera?.parameters?.pictureSize?.width},height:${camera?.parameters?.pictureSize?.height}")
            if (orientation != -1) camera?.setDisplayOrientation(orientation)
            startPreview(surfaceTexture)
        } catch (ex: Exception) {
            closeCamera()
            checkListener?.checkPixels(pixels, false)
            e("Error starting camera preview: $ex")
        }
    }

    private fun startPreview(surfaceTexture: SurfaceTexture?) {
        camera?.setPreviewTexture(surfaceTexture)
        camera?.startPreview()
    }

    fun getCameraHeight(): Int = cameraHeight
    fun getCameraWidth(): Int = cameraWidth
    fun getPreviewWidth(): Int = camera?.parameters?.previewSize?.width ?: 0
    fun getPreviewHeight(): Int = camera?.parameters?.previewSize?.height ?: 0
    fun getDisplayOrientation(): Int = if (orientation == -1) displayOrientation else orientation
    fun getCamera(): Camera? = camera
}